搜索 K
Appearance
博客正在加载中...
Appearance
由于 Java 旧的时间 API 不好用,市面上出现了不少关于时间的 API,例如开源的 Joda Time,应用广泛;JDK 团队邀请 Joda Time 的作者 Stephen Colebourne 共同设计了 java.time API,并在 Java8 引入。
主要的类如下:
LocalDate,LocalTime,LocalDateTime;DateTimeFormatter:格式化日期,可取代 SimpleDateFormat;ZonedDateTime;Instant;ZoneId,ZoneOffset;Duration和 Period;其他改进:
我们首先介绍这 3 个:
LocalDate,表示本地日期LocalTime,表示本地时间LocalDateTime,表示本地日期和时间LocalDateTime 的源码可以发现,LocalDateTime 是由 LocalDate 和 LocalTime 来表示的 LocalDate d = LocalDate.now();
LocalTime t = LocalTime.now();
LocalDateTime dt = LocalDateTime.now();
System.out.println(d); //2022-12-22
System.out.println(t); //12:53:28.332
System.out.println(dt); //2022-12-22T12:53:28.332说明:
now() 获取到的总是以当前默认时区返回的获取一个某个时间的属性:
getYear()getMonth()getMonthValue()getDayOfMonth()getHour()getMinute()getSecond()getDayOfYear()getDayOfWeek()还可以用 get 方法获取指定字段的 int 值:
LocalDateTime ldt = LocalDateTime.of(2022, 1, 1, 2, 3, 4, 56789);//2022-1-1 2:3:1
int i1 = ldt.get(ChronoField.MINUTE_OF_DAY); //123 指的是目前已经过了2*小时 + 3分钟= 123分钟了
int i2 = ldt.get(ChronoField.MINUTE_OF_HOUR); //3 指的是目前在当前这个小时内,已经过了3分钟关于 ChronoField 类,我们下回分解
我们可以在创建对象的时候,指定时间:
LocalDate d2 = LocalDate.of(2022, 5, 21);
LocalTime t2 = LocalTime.of(13,14, 15);
LocalDateTime dt2 = LocalDateTime.of(2022,5, 21, 13, 14, 15);
LocalDateTime dt3 = LocalDateTime.of(d2, t2);
System.out.println("d2: " + d2); //d2: 2022-05-21
System.out.println("t2: " + t2); //t2: 13:14:15
System.out.println("dt2: " + dt2); //dt2: 2022-05-21T13:14:15
System.out.println("dt3: " + dt3); //dt3: 2022-05-21T13:14:15第 4 行我们用了 LocalDate 和 LocalTime 创建 LocalDateTime ,也可以反过来:
LocalDate d3 = dt2.toLocalDate();
LocalTime t3 = dt2.toLocalTime();
System.out.println("d3: " + d3); //d3: 2022-05-21
System.out.println("t3: " + t3); //t3: 13:14:15还可以通过字符串来创建:
// 通过字符串创建对象
LocalDateTime dt4 = LocalDateTime.parse("2022-5-21T21:13:14");
LocalDate d4 = LocalDate.parse("2022-5-21");
LocalTime t6 = LocalTime.parse("15:16:17");注意 ISO 8601 规定的日期和时间分隔符是 T。标准格式如下:
其他注意事项:
构造方法得是合理的参数值,例如小时的范围是 0~23,如果超过(例如设置成 52),运行的时候会抛出异常:
Exception in thread "main" java.time.DateTimeException: Invalid value for HourOfDay (valid values 0 - 23): 52
at java.time.temporal.ValueRange.checkValidValue(ValueRange.java:311)
at java.time.temporal.ChronoField.checkValidValue(ChronoField.java:703)
at java.time.LocalTime.of(LocalTime.java:317)
at TestLocalDateTime.main(TestLocalDateTime.java:17)可以用 withXXX() 调整时间和日期
withYear()withMonth()withDayOfMonth()withHour(). 例如:withHour(15) 会把 10:11:12 变为 15:11:12:withMinute()withSecond() LocalDateTime dt = LocalDateTime.of(2022,5, 21, 13, 14, 15);
dt = dt.withYear(2122);
dt = dt.withHour(05); //调整成5点
System.out.println(dt); //2122-05-21T05:14:15注意:月份的加减会自动调整日期,例如从 10 月 31 日减去一个月,会得到 9 月 30 日,因为 9 月没有 31
LocalDateTime 还有一个通用的 with() 方法允许我们做更复杂的调整,我们后面会提到。
由于代码执行需要一定的时间,需要注意分开创建的时间对象是不一样的(1 毫秒不同也不行,除非你能保证两者运行的时间差距在 1 毫秒,一些性能好的计算机可能做到,但我们不能把希望寄托于未知 🧐)。
LocalTime t4 = LocalTime.now();
LocalTime t5 = LocalTime.now();
System.out.println(t4.compareTo(t5)); //-1我们还可以用 isBefore()、isAfter() 方法来判断,其返回 Boolean 值
LocalDateTime 提供了方便的加减方法:
LocalDateTime dt = LocalDateTime.of(2022,5, 21, 13, 14, 15);
dt = dt.plusDays(5); // sub 5 days
dt = dt.plusDays(1); // add 1 day
dt = dt.plusHours(1); //sub 1 hour
dt = dt.minusHours(3); //add 3 hours
System.out.println(dt); //2022-05-27T11:14:15
minus有减法的意思。可以对秒数、分钟、小时、天数、周数、月份、年份进行加减。
可以用链式调用,简化代码:
dt = LocalDateTime.of(2022,5, 21, 13, 14, 15);
dt = dt.plusDays(5).minusDays(1).plusHours(1).minusHours(3);
System.out.println(dt); //2022-05-25T11:14:15注意:月份的加减会自动调整日期,例如从 10 月 31 日减去一个月,会得到 9 月 30 日,因为 9 月没有 31
LocalDateTime 无法与时间戳进行转换,因为 LocalDateTime 没有时区,无法确定某一时刻。
后面我们会介绍 ZonedDateTime,其相当于 LocalDateTime 加时区的组合,可以与 long 表示的时间戳进行转换。
LocalDate,LocalTime,LocalDateTime 的常用方法如下:
| 方法名 | 用处 | 示例 |
|---|---|---|
now() | 获取当前默认时区的当前时间 | LocalDate.now(); |
getXXX() | 获取时间的某个字段 | getYear() 获取年份 |
of() | 指定时间 | LocalDate.of(2022, 5, 21); |
parse(String s) | 根据字符串来指定时间 | LocalDate.parse("2022-5-21"); |
withXXX() | 调整时间和日期 | dt.withYear(2122); |
compareTo() isBefore() isAfter() | 比较时间 | t4.compareTo(t5) |
plusXXX(), minusXXX() | 加减时间 | dt.plusDays(5) |